// 导入 Dio 库，用于进行网络请求
import 'package:dio/dio.dart';
import 'package:flutterDemo/http/cookie_intercepter.dart';
// 导入 HttpMethod 类，该类定义了 HTTP 请求方法
import 'package:flutterDemo/http/http_method.dart';
import 'package:flutterDemo/http/print_log_interceptor.dart';
import 'package:flutterDemo/http/rsp_interceptor.dart';

/// DioInstance 类是一个单例类，用于管理 Dio 实例并提供 HTTP 请求方法
class DioInstance {
  // 私有静态变量，用于存储单例实例
  static DioInstance? _instance;
  // 私有构造函数，确保该类不能在外部被实例化
  DioInstance._();

  /// 静态方法，用于获取单例实例
  ///
  /// 如果实例不存在，则创建一个新实例；否则，返回现有的实例
  static DioInstance instance() {
    return _instance ??= DioInstance._();
  }

  // 私有 Dio 实例，用于发送网络请求
  final Dio _dio = Dio();
  // 私有变量，用于存储默认的超时时间
  final _defaultTime = const Duration(seconds: 30);

  /// 用于初始化 Dio 实例的方法
  ///
  /// [baseUrl] 是网络请求的基础 URL
  /// [httpMethod] 是 HTTP 请求方法，默认为 GET
  /// [connectTimeout] 是连接超时时间
  /// [sendTimeout] 是发送超时时间
  /// [receiveTimeout] 是接收超时时间
  /// [responseType] 是响应数据类型，默认为 JSON
  /// [contentType] 是请求的内容类型
  void initDio({
    required String baseUrl,
    String? httpMethod = HttpMethod.GET,
    Duration? connectTimeout,
    Duration? sendTimeout,
    Duration? receiveTimeout,
    ResponseType? responseType = ResponseType.json,
    String? contentType,
  }) {
    // 设置 Dio 实例的选项
    _dio.options = BaseOptions(
        // 设置 HTTP 请求方法
        method: "GET",
        // 设置网络请求的基础 URL
        baseUrl: "https://www.wanandroid.com/",
        // 设置连接超时时间，默认为默认超时时间
        connectTimeout: connectTimeout ?? _defaultTime,
        // 设置发送超时时间，默认为默认超时时间
        sendTimeout: sendTimeout ?? _defaultTime,
        // 设置接收超时时间，默认为默认超时时间
        receiveTimeout: receiveTimeout ?? _defaultTime,
        // 设置响应数据类型
        responseType: responseType,
        // 设置请求的内容类型
        contentType: contentType);
    //添加cookie拦截器
    _dio.interceptors.add(CookieIntercepter());
    // 添加请求日志拦截器
    _dio.interceptors.add(PrintLogInterceptor());
    //添加统一返回值处理拦截器
    _dio.interceptors.add(ResponseInterceptor());
  }

  /// 用于发送 GET 请求的方法
  ///
  /// [path] 是请求路径
  /// [param] 是请求的查询参数
  /// [options] 是请求选项
  /// [cancelToken] 是请求的取消令牌
  ///
  /// 返回一个包含响应数据的 Future
  Future<Response> get({
    required String path,
    Map<String, dynamic>? param,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    return await _dio.get(path,
        // 设置请求的查询参数
        queryParameters: param,
        // 设置请求选项，默认为 GET 方法和默认超时时间
        options: options ??
            Options(
              method: HttpMethod.GET,
              receiveTimeout: _defaultTime,
              sendTimeout: _defaultTime,
            ),
        // 设置请求的取消令牌
        cancelToken: cancelToken);
  }

  /// 用于发送 POST 请求的方法
  ///
  /// [path] 是请求路径
  /// [data] 是请求体数据
  /// [queryParameters] 是请求的查询参数
  /// [options] 是请求选项
  /// [cancelToken] 是请求的取消令牌
  ///
  /// 返回一个包含响应数据的 Future
  Future<Response> post({
    required String path,
    Object? data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? cancelToken,
  }) async {
    return await _dio.post(path,
        // 设置请求的查询参数
        queryParameters: queryParameters,
        // 设置请求体数据
        data: data,
        // 设置请求的取消令牌
        cancelToken: cancelToken,
        // 设置请求选项，默认为 GET 方法和默认超时时间
        options: options ??
            Options(
              method: HttpMethod.POST,
              receiveTimeout: _defaultTime,
              sendTimeout: _defaultTime,
            ));
  }
}
